/*
 *                    BioJava development code
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  If you do not have a copy,
 * see:
 *
 *      http://www.gnu.org/copyleft/lesser.html
 *
 * Copyright for this code is held jointly by the individual
 * authors.  These should be listed in @author doc comments.
 *
 * For more information on the BioJava project and its aims,
 * or to join the biojava-l mailing list, visit the home page
 * at:
 *
 *      http://www.biojava.org/
 *
 * Created on 15.08.2007
 * @author Asia Grzibovska
 *
 */

package uk.ac.sanger;

import org.xml.sax.*;             // The main SAX package
import java.util.*;               // Hashtable, lists, and so on


public class WritebackXMLParser extends org.xml.sax.helpers.DefaultHandler {

	StringBuffer accumulator;                    // Accumulate text
	String first, message, feature,loc,property; // Remember text
	Attributes my_attributes;
	List attributes1= new ArrayList();

	List features;
	//	see class FeatureBean.java
	FeatureBean f = new FeatureBean();

	// Called at the beginning of parsing.  We use it as an init() method
	public void startDocument() {
		accumulator = new StringBuffer();
		features = new ArrayList();
		f = new FeatureBean();
	}

	public FeatureBean[] getFeatures(){
		return (FeatureBean[]) features.toArray(new FeatureBean[features.size()]);
	}

	// When the parser encounters plain text (not XML elements), it calls
	// this method, which accumulates them in a string buffer.
	// Note that this method may be called multiple times, even with no
	// intervening elements.
	public void characters(char[] buffer, int start, int length) {
		accumulator.append(buffer, start, length);
	}

	// At the beginning of each new element, erase any accumulated text.
	public void startElement(String namespaceURL, String localName,
			String qname, Attributes attributes) 
	{   	 	
		if (localName.equals("LOC")) {  // Store feature name
			feature = accumulator.toString().trim();
		};
		if (localName.equals("FEATURE")) {   
			// store list of FEATURE attributes, use later in EndElement 
			if (attributes1 == null) {
				attributes1 = new ArrayList();
			}
			if (attributes.getLocalName(0) != null) {
				for (int i = 0; i < attributes.getLength(); i++) {
					attributes1.add(attributes.getLocalName(i) + " : " + attributes.getValue(i)); 
				}}         
		};
		accumulator.setLength(0);
		my_attributes=attributes;
	}

	// Take special action when we reach the end of selected elements.
	// Although we don't use a validating parser, this method does assume
	// that the web.xml file we're parsing is valid.
	public void endElement(String namespaceURL, String localName, String qname)
	{ 
		try{
			String[] tmp=null;
			////////////////////// Store element/////////////////////
			if (localName.equals("MESSAGE")) {  
				message = accumulator.toString().trim();
				//add to beans
				f.setCommitMsg(message);
			}
			/////////////////////// Store element///////////////////
			else if (localName.equals("LOC")) {  
				loc = accumulator.toString().trim();
				property=null;
				if (my_attributes.getLocalName(0) != null) {
					for (int i = 0; i < my_attributes.getLength(); i++) {
						// add to beans
						if(my_attributes.getLocalName(i).equals("segment"))
							f.setSegment(my_attributes.getValue(i).trim());
						if(my_attributes.getLocalName(i).equals("range")){
							f.setStart(my_attributes.getValue(i).toString().split(":",3)[0].trim());
							f.setEnd(my_attributes.getValue(i).toString().split(":",3)[1].trim());
							f.setStrand(my_attributes.getValue(i).toString().split(":",3)[2].trim());}
					}
				}
			}
			/////////////////////// Store element/////////////////// 
			else if (localName.equals("PROPERTY")) {  // Store element
				property = accumulator.toString().trim();
				// store list of attributes
				if (my_attributes.getLocalName(0) != null){
					for (int i = 0; i < my_attributes.getLength(); i++) {
						//add to beans
						if(my_attributes.getLocalName(i).equals("phase"))
							f.setPhase(my_attributes.getValue(i).trim());
						else if(my_attributes.getLocalName(i).equals("score"))
							f.setScore(my_attributes.getValue(i).trim());
						else if(my_attributes.getLocalName(i).equals("link"))
							f.setLinks(my_attributes.getValue(i).trim());
						//else if(my_attributes.getLocalName(i).equals("system"))
						//	f.setSystem(my_attributes.getValue(i).trim());
						else if(my_attributes.getLocalName(i).equals("system_uri"))
							f.setSystem_uri(my_attributes.getValue(i).trim());
						else if(my_attributes.getLocalName(i).equals("note"))
							f.setNotes(my_attributes.getValue(i).trim());
						else if(my_attributes.getLocalName(i).equals("groups"))
							f.setGroups(my_attributes.getValue(i).trim());
						else if(my_attributes.getLocalName(i).equals("user"))
							f.setUser(my_attributes.getValue(i).trim());
					}
				}
			}

			/////////////////////// Store element///////////////////
			else if (localName.equals("UPDATE")) 
				f.setUpdate(my_attributes.getValue(0).trim());
			/////////////////////// Store element///////////////////
			else if (localName.equals("DELETE")) 
				f.setDelete(my_attributes.getValue(0).trim());
			/////////////////////// Store element///////////////////
			else if (localName.equals("FEATURE")) { 
				//use saved "attributes1" from StartElement 
				if (attributes1.size() > 0) {
					for (int i = 0; i < attributes1.size(); i++) {
						//add to beans
						tmp=attributes1.get(i).toString().split(":",2);
						if(tmp[0].trim().equals("featureid"))
							f.setFeatureid(tmp[1].trim());					
						if(tmp[0].trim().equals("featuretype"))
							f.setFeaturetype(tmp[1].trim());
						if(tmp[0].trim().equals("method"))
							f.setMethod(tmp[1].trim());
					}
				}
				attributes1.clear();			
			}	
		}catch (Exception e) {
			e.printStackTrace();}
	}

	////////////////////////////////////////////////////////////////
	// Called at the end of parsing.  Used here to print our results.
	public void endDocument() {
		try{
			//add collected data to list of FeatureBeans 			
			features.add(f);

		}catch (Exception e) {
			e.printStackTrace();}
	}

	// Issue a warning
	public void warning(SAXParseException exception) {
		System.err.println("WARNING: line " + exception.getLineNumber() + ": "+
				exception.getMessage());
	}

	// Report a parsing error
	public void error(SAXParseException exception) {
		System.err.println("ERROR: line " + exception.getLineNumber() + ": " +
				exception.getMessage());
	}

	// Report a non-recoverable error and exit
	public void fatalError(SAXParseException exception) throws SAXException {
		System.err.println("FATAL: line " + exception.getLineNumber() + ": " +
				exception.getMessage());
		throw(exception);
	}


}
